﻿namespace com.oakwoodsys.ConsultantCareDao
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Xml;

    using com.oakwoodsys.Extensions.DateTimeExtensions;

    public class CalendarEvent : InternalBase
    {
        #region Fields

        Guid? _ActivityID;
        bool? _AllDayEvent;
        string _Category;
        string _Description;
        DateTime? _EndTime;
        string _Location;
        CalendarRecurrence _Recurrence;
        DateTime? _StartTime;
        string _Title;

        #endregion Fields

        #region Properties

        public Guid ActivityID
        {
            get{
                return _ActivityID.HasValue ? _ActivityID.Value : Guid.Empty;
            }
            set
            {
                if ( ( value != _ActivityID ) )
                {
                    OnPropertyChanging( "ActivityID", _ActivityID );
                    _ActivityID = value;
                    OnPropertyChanged( "ActivityID" );
                }
            }
        }

        public bool AllDayEvent
        {
            get
            {
                return _AllDayEvent.HasValue ? _AllDayEvent.Value : false;
            }
            set
            {
                if ( ( value != _AllDayEvent ) )
                {
                    OnPropertyChanging( "AllDayEvent", _AllDayEvent );
                    _AllDayEvent = value;
                    OnPropertyChanged( "AllDayEvent" );
                }
            }
        }

        public string Category
        {
            get
            {
                return _Category;
            }
            set
            {
                if ( ( value != _Category ) )
                {
                    OnPropertyChanging( "Category", _Category );
                    _Category = value;
                    OnPropertyChanged( "Category" );
                }
            }
        }

        public string Description
        {
            get
            {
                return _Description;
            }
            set
            {
                if ( ( value != _Description ) )
                {
                    OnPropertyChanging( "Description", _Description );
                    _Description = value;
                    OnPropertyChanged( "Description" );
                }
            }
        }

        public DateTime EndDate
        {
            get
            {
                return _EndTime.HasValue ? _EndTime.Value : StartTime;
            }
            set
            {
                if ( ( value != _EndTime ) )
                {
                    OnPropertyChanging( "EndTime", _EndTime );
                    _EndTime = value;
                    OnPropertyChanged( "EndTime" );
                }
            }
        }

        public int EventType
        {
            get
            {
                return IsRecurring ? 1 : 0;
            }
        }

        public int? Id
        {
            get;
            set;
        }

        public bool IsRecurring
        {
            get
            {
                return Recurrence.IsRecurring;
            }
        }

        public string Location
        {
            get
            {
                return string.IsNullOrEmpty( _Location ) ? string.Empty : _Location;
            }
            set
            {
                if ( ( value != _Location ) )
                {
                    OnPropertyChanging( "Location", _Location );
                    _Location = value;
                    OnPropertyChanged( "Location" );
                }
            }
        }

        public CalendarRecurrence Recurrence
        {
            get
            {
                return _Recurrence ?? new CalendarRecurrenceNone( );
            }
            set
            {
                if ( ( value != _Recurrence ) )
                {
                    OnPropertyChanging( "Recurrence", _Recurrence );
                    _Recurrence = value;
                    OnPropertyChanged( "Recurrence" );
                }
            }
        }

        public string RecurrenceData
        {
            get
            {
                return Recurrence.RecurrenceData;
            }
        }

        public DateTime StartTime
        {
            get
            {
                return _StartTime.HasValue ? _StartTime.Value : DateTime.Now;
            }
            set
            {
                if ( ( value != _StartTime ) )
                {
                    OnPropertyChanging( "StartTime", _StartTime );
                    _StartTime = value;
                    OnPropertyChanged( "StartTime" );
                }
            }
        }

        public string Title
        {
            get
            {
                return _Title;
            }
            set
            {
                if ( ( value != _Title ) )
                {
                    OnPropertyChanging( "Title", _Title );
                    _Title = value;
                    OnPropertyChanged( "Title" );
                }
            }
        }

        public Guid UniqueId
        {
            get;
            set;
        }

        #endregion Properties
    }

    public class CalendarRecurrence : InternalBase
    {
        #region Fields

        internal const string END = "$end";
        internal const string REPEAT = "$repeat";
        internal const string REPEATINSTANCES = "$repeatInstances";
        internal const string WINDOWEND = "$windowEnd";

        const string ENDAFTERNOCCURRENCES = "<repeatInstances>$repeatInstances</repeatInstances>";
        const string ENDBYDATE = "<windowEnd>$windowEnd</windowEnd>";
        const string NOENDDATE = "<repeatForever>FALSE</repeatForever>";
        const string RECURRENCEDATA = "<recurrence><rule><firstDayOfWeek>su</firstDayOfWeek><repeat>$repeat</repeat>$end</rule></recurrence>";

        EndValue? _End;
        int? _EndAfterNOccurrences;
        DateTime? _EndByDate;
        DateTime? _StartTime;

        #endregion Fields

        #region Enumerations

        public enum EndValue
        {
            NoEndDate,
            EndAfterNOccurrences,
            EndByDate
        }

        #endregion Enumerations

        #region Properties

        public EndValue End
        {
            get
            {
                return _End.HasValue ? _End.Value : EndValue.EndAfterNOccurrences;
            }
            set
            {
                if ( ( value != _End ) )
                {
                    OnPropertyChanging( "End", _End );
                    _End = value;
                    OnPropertyChanged( "End" );
                }
            }
        }

        public int EndAfterNOccurrences
        {
            get
            {
                return _EndAfterNOccurrences.HasValue ? _EndAfterNOccurrences.Value : 1;
            }
            set
            {
                if ( ( value != _EndAfterNOccurrences ) )
                {
                    OnPropertyChanging( "EndAfterNOccurrences", _EndAfterNOccurrences );
                    _EndAfterNOccurrences = value;
                    OnPropertyChanged( "EndAfterNOccurrences" );
                }
            }
        }

        public DateTime EndByDate
        {
            get
            {
                return _EndByDate.HasValue ? _EndByDate.Value : DateTime.Now;
            }
            set
            {
                if ( ( value != _EndByDate ) )
                {
                    OnPropertyChanging( "EndByDate", _EndByDate );
                    _EndByDate = value;
                    OnPropertyChanged( "EndByDate" );
                }
            }
        }

        public virtual bool IsRecurring
        {
            get
            {
                return true;
            }
        }

        //public DateTime StartTime
        //{
        //    get
        //    {
        //        return _StartTime.HasValue ? _StartTime.Value : DateTime.Now;
        //    }
        //    set
        //    {
        //        if ( ( value != _StartTime ) )
        //        {
        //            OnPropertyChanging( "StartTime", _StartTime );
        //            _StartTime = value;
        //            OnPropertyChanged( "StartTime" );
        //        }
        //    }
        //}
        public virtual string RecurrenceData
        {
            get
            {
                switch ( End )
                {
                    case EndValue.NoEndDate:
                        return RECURRENCEDATA.Replace( END, NOENDDATE );
                    case EndValue.EndAfterNOccurrences:
                        return RECURRENCEDATA.Replace( END, ENDAFTERNOCCURRENCES ).Replace( REPEATINSTANCES, EndAfterNOccurrences.ToString( ) );
                    case EndValue.EndByDate:
                        return RECURRENCEDATA.Replace( END, ENDBYDATE ).Replace( WINDOWEND, XmlConvert.ToString( EndByDate, "yyyy-MM-ddTHH:mm:ssZ" ) );
                    default:
                        break;
                }
                return RECURRENCEDATA.Replace( END, ENDAFTERNOCCURRENCES ).Replace( REPEATINSTANCES, EndAfterNOccurrences.ToString( ) );
            }
        }

        #endregion Properties
    }

    public class CalendarRecurrenceDaily : CalendarRecurrence
    {
        #region Fields

        const string EVERYNDAYS = "<daily dayFrequency=\"$frequency\" />";
        const string EVERYWEEKDAY = "<daily weekday=\"TRUE\" />";
        const string FREQUENCY = "$frequency";

        int? _Frequency;
        RecurrenceValue? _Recurrence;

        #endregion Fields

        #region Enumerations

        public enum RecurrenceValue
        {
            EveryNDays,
            EveryWeekday
        }

        #endregion Enumerations

        #region Properties

        public int Frequency
        {
            get
            {
                return _Frequency.HasValue ? _Frequency.Value : 1;
            }
            set
            {
                if ( ( value != _Frequency ) )
                {
                    OnPropertyChanging( "Frequency", _Frequency );
                    _Frequency = value;
                    OnPropertyChanged( "Frequency" );
                }
            }
        }

        public RecurrenceValue Recurrence
        {
            get
            {
                return _Recurrence.HasValue ? _Recurrence.Value : RecurrenceValue.EveryWeekday;
            }
            set
            {
                if ( ( value != _Recurrence ) )
                {
                    OnPropertyChanging( "Recurrence", _Recurrence );
                    _Recurrence = value;
                    OnPropertyChanged( "Recurrence" );
                }
            }
        }

        public override string RecurrenceData
        {
            get
            {
                switch ( Recurrence )
                {
                    case RecurrenceValue.EveryWeekday:
                        return base.RecurrenceData.Replace( REPEAT, EVERYWEEKDAY );
                    case RecurrenceValue.EveryNDays:
                    default:
                        break;
                }
                return base.RecurrenceData.Replace( REPEAT, EVERYNDAYS ).Replace( FREQUENCY, Frequency.ToString( ) );
            }
        }

        #endregion Properties
    }

    public class CalendarRecurrenceMonthly : CalendarRecurrence
    {
        #region Fields

        const string DAY = "$day";
        const string FREQUENCY = "$frequency";
        const string SPECIFICDAY = "<monthly monthFrequency=\"$frequency\" day=\"$day\" />";
        const string WEEKDAY = "$weekday";
        const string WEEKDAYOFMONTH = "<monthlyByDay $day=\"TRUE\" weekdayOfMonth=\"$weekday\" monthFrequency=\"$frequency\" />";

        string[] weekday = { "su", "mo", "tu", "we", "th", "fr", "sa" };
        string[] weekdayOfMonth = { "first", "second", "third", "fourth", "last" };
        int? _Frequency;
        RecurrenceValue? _Recurrence;
        int? _SpecificDay;
        WeekdayValue? _Weekday;
        WeekdayOfMonthValue? _WeekdayOfMonth;

        #endregion Fields

        #region Enumerations

        public enum RecurrenceValue
        {
            SpecificDay,
            WeekdayOfMonth
        }

        public enum WeekdayOfMonthValue
        {
            First = 0,
            Second = 1,
            Third = 2,
            Fourth = 3,
            Last = 4
        }

        public enum WeekdayValue
        {
            Sunday = 0,
            Monday = 1,
            Tuesday = 2,
            Wednesday = 3,
            Thursday = 4,
            Friday = 5,
            Saturday = 6
        }

        #endregion Enumerations

        #region Properties

        public int Frequency
        {
            get
            {
                return _Frequency.HasValue ? _Frequency.Value : 1;
            }
            set
            {
                if ( ( value != _Frequency ) )
                {
                    OnPropertyChanging( "Frequency", _Frequency );
                    _Frequency = value;
                    OnPropertyChanged( "Frequency" );
                }
            }
        }

        public RecurrenceValue Recurrence
        {
            get
            {
                return _Recurrence.HasValue ? _Recurrence.Value : RecurrenceValue.SpecificDay;
            }
            set
            {
                if ( ( value != _Recurrence ) )
                {
                    OnPropertyChanging( "Recurrence", _Recurrence );
                    _Recurrence = value;
                    OnPropertyChanged( "Recurrence" );
                }
            }
        }

        public override string RecurrenceData
        {
            get
            {
                switch ( Recurrence )
                {
                    case RecurrenceValue.WeekdayOfMonth:
                        return base.RecurrenceData.Replace( REPEAT, WEEKDAYOFMONTH ).Replace( FREQUENCY, Frequency.ToString( ) ).Replace( DAY, weekday[ ( int ) Weekday ] ).Replace( WEEKDAY, weekdayOfMonth[ ( int ) WeekdayOfMonth ] );
                    case RecurrenceValue.SpecificDay:
                    default:
                        break;
                }
                return base.RecurrenceData.Replace( REPEAT, SPECIFICDAY ).Replace( FREQUENCY, Frequency.ToString( ) ).Replace( DAY, SpecificDay.ToString( ) );
            }
        }

        public int SpecificDay
        {
            get
            {
                return _SpecificDay.HasValue ? _SpecificDay.Value : 1;
            }
            set
            {
                if ( ( value != _SpecificDay ) )
                {
                    OnPropertyChanging( "SpecificDay", _SpecificDay );
                    _SpecificDay = value;
                    OnPropertyChanged( "SpecificDay" );
                }
            }
        }

        public WeekdayValue Weekday
        {
            get
            {
                return _Weekday.HasValue ? _Weekday.Value : WeekdayValue.Sunday;
            }
            set
            {
                if ( ( value != _Weekday ) )
                {
                    OnPropertyChanging( "Weekday", _Weekday );
                    _Weekday = value;
                    OnPropertyChanged( "Weekday" );
                }
            }
        }

        public WeekdayOfMonthValue WeekdayOfMonth
        {
            get
            {
                return _WeekdayOfMonth.HasValue ? _WeekdayOfMonth.Value : WeekdayOfMonthValue.First;
            }
            set
            {
                if ( ( value != _WeekdayOfMonth ) )
                {
                    OnPropertyChanging( "WeekdayOfMonth", _WeekdayOfMonth );
                    _WeekdayOfMonth = value;
                    OnPropertyChanged( "WeekdayOfMonth" );
                }
            }
        }

        #endregion Properties
    }

    public class CalendarRecurrenceNone : CalendarRecurrence
    {
        #region Properties

        public override bool IsRecurring
        {
            get
            {
                return false;
            }
        }

        public override string RecurrenceData
        {
            get
            {
                return string.Empty;
            }
        }

        #endregion Properties
    }

    public class CalendarRecurrenceWeekly : CalendarRecurrence
    {
        #region Fields

        const string DAY = "$day";
        const string EVERYNWEEKS = "<weekly $day weekFrequency=\"$frequency\" />";
        const string FREQUENCY = "$frequency";
        const string WEEKDAY = "{0}=\"TRUE\" ";

        string[] weekday = { "su", "mo", "tu", "we", "th", "fr", "sa" };
        int? _Frequency;
        bool? _Friday;
        bool? _Monday;
        bool? _Saturday;
        bool? _Sunday;
        bool? _Thursday;
        bool? _Tuesday;
        bool? _Wednesday;

        #endregion Fields

        #region Enumerations

        enum WeekdayValue
        {
            Sunday = 0,
            Monday = 1,
            Tuesday = 2,
            Wednesday = 3,
            Thursday = 4,
            Friday = 5,
            Saturday = 6
        }

        #endregion Enumerations

        #region Properties

        public int Frequency
        {
            get
            {
                return _Frequency.HasValue ? _Frequency.Value : 1;
            }
            set
            {
                if ( ( value != _Frequency ) )
                {
                    OnPropertyChanging( "Frequency", _Frequency );
                    _Frequency = value;
                    OnPropertyChanged( "Frequency" );
                }
            }
        }

        public bool Friday
        {
            get
            {
                return _Friday.HasValue ? _Friday.Value : false;
            }
            set
            {
                if ( ( value != _Friday ) )
                {
                    OnPropertyChanging( "Friday", _Friday );
                    _Friday = value;
                    OnPropertyChanged( "Friday" );
                }
            }
        }

        public bool Monday
        {
            get
            {
                return _Monday.HasValue ? _Monday.Value : false;
            }
            set
            {
                if ( ( value != _Monday ) )
                {
                    OnPropertyChanging( "Monday", _Monday );
                    _Monday = value;
                    OnPropertyChanged( "Monday" );
                }
            }
        }

        public override string RecurrenceData
        {
            get
            {
                StringBuilder sb = new StringBuilder( );
                if ( Sunday )
                    sb.AppendFormat( WEEKDAY, weekday[ ( int ) WeekdayValue.Sunday ] );
                if ( Monday )
                    sb.AppendFormat( WEEKDAY, weekday[ ( int ) WeekdayValue.Monday ] );
                if ( Tuesday )
                    sb.AppendFormat( WEEKDAY, weekday[ ( int ) WeekdayValue.Tuesday ] );
                if ( Wednesday )
                    sb.AppendFormat( WEEKDAY, weekday[ ( int ) WeekdayValue.Wednesday ] );
                if ( Thursday )
                    sb.AppendFormat( WEEKDAY, weekday[ ( int ) WeekdayValue.Thursday ] );
                if ( Friday )
                    sb.AppendFormat( WEEKDAY, weekday[ ( int ) WeekdayValue.Friday ] );
                if ( Saturday )
                    sb.AppendFormat( WEEKDAY, weekday[ ( int ) WeekdayValue.Saturday ] );
                string day = sb.ToString( ).Trim( );
                sb = null;
                return base.RecurrenceData.Replace( REPEAT, EVERYNWEEKS ).Replace( FREQUENCY, Frequency.ToString( ) ).Replace( DAY, day );
            }
        }

        public bool Saturday
        {
            get
            {
                return _Saturday.HasValue ? _Saturday.Value : false;
            }
            set
            {
                if ( ( value != _Saturday ) )
                {
                    OnPropertyChanging( "Saturday", _Saturday );
                    _Saturday = value;
                    OnPropertyChanged( "Saturday" );
                }
            }
        }

        public bool Sunday
        {
            get
            {
                return _Sunday.HasValue ? _Sunday.Value : false;
            }
            set
            {
                if ( ( value != _Sunday ) )
                {
                    OnPropertyChanging( "Sunday", _Sunday );
                    _Sunday = value;
                    OnPropertyChanged( "Sunday" );
                }
            }
        }

        public bool Thursday
        {
            get
            {
                return _Thursday.HasValue ? _Thursday.Value : false;
            }
            set
            {
                if ( ( value != _Thursday ) )
                {
                    OnPropertyChanging( "Thursday", _Thursday );
                    _Thursday = value;
                    OnPropertyChanged( "Thursday" );
                }
            }
        }

        public bool Tuesday
        {
            get
            {
                return _Tuesday.HasValue ? _Tuesday.Value : false;
            }
            set
            {
                if ( ( value != _Tuesday ) )
                {
                    OnPropertyChanging( "Tuesday", _Tuesday );
                    _Tuesday = value;
                    OnPropertyChanged( "Tuesday" );
                }
            }
        }

        public bool Wednesday
        {
            get
            {
                return _Wednesday.HasValue ? _Wednesday.Value : false;
            }
            set
            {
                if ( ( value != _Wednesday ) )
                {
                    OnPropertyChanging( "Wednesday", _Wednesday );
                    _Wednesday = value;
                    OnPropertyChanged( "Wednesday" );
                }
            }
        }

        #endregion Properties
    }

    public class CalendarRecurrenceYearly : CalendarRecurrence
    {
        #region Fields

        const string DAY = "$day";
        const string FREQUENCY = "$frequency";
        const string MONTH = "$month";
        const string SPECIFICDAY = "<yearly yearFrequency=\"$frequency\" month=\"$month\" day=\"$day\" />";
        const string WEEKDAY = "$weekday";
        const string WEEKDAYOFMONTH = "<yearlyByDay yearFrequency=\"$frequency\" $day=\"TRUE\" weekdayOfMonth=\"$weekday\" month=\"$month\" />";

        string[] weekday = { "su", "mo", "tu", "we", "th", "fr", "sa" };
        string[] weekdayOfMonth = { "first", "second", "third", "fourth", "last" };
        int? _Frequency;
        MonthValue? _Month;
        RecurrenceValue? _Recurrence;
        int? _SpecificDay;
        WeekdayValue? _Weekday;
        WeekdayOfMonthValue? _WeekdayOfMonth;

        #endregion Fields

        #region Enumerations

        public enum MonthValue
        {
            January = 1,
            February = 2,
            March = 3,
            April = 4,
            May = 5,
            June = 6,
            July = 7,
            August = 8,
            September = 9,
            October = 10,
            November = 11,
            December = 12
        }

        public enum RecurrenceValue
        {
            SpecificDay,
            WeekdayOfMonth
        }

        public enum WeekdayOfMonthValue
        {
            First = 0,
            Second = 1,
            Third = 2,
            Fourth = 3,
            Last = 4
        }

        public enum WeekdayValue
        {
            Sunday = 0,
            Monday = 1,
            Tuesday = 2,
            Wednesday = 3,
            Thursday = 4,
            Friday = 5,
            Saturday = 6
        }

        #endregion Enumerations

        #region Properties

        public int Frequency
        {
            get
            {
                return _Frequency.HasValue ? _Frequency.Value : 1;
            }
            set
            {
                if ( ( value != _Frequency ) )
                {
                    OnPropertyChanging( "Frequency", _Frequency );
                    _Frequency = value;
                    OnPropertyChanged( "Frequency" );
                }
            }
        }

        public MonthValue Month
        {
            get
            {
                return _Month.HasValue ? _Month.Value : MonthValue.January;
            }
            set
            {
                if ( ( value != _Month ) )
                {
                    OnPropertyChanging( "Month", _Month );
                    _Month = value;
                    OnPropertyChanged( "Month" );
                }
            }
        }

        public RecurrenceValue Recurrence
        {
            get
            {
                return _Recurrence.HasValue ? _Recurrence.Value : RecurrenceValue.SpecificDay;
            }
            set
            {
                if ( ( value != _Recurrence ) )
                {
                    OnPropertyChanging( "Recurrence", _Recurrence );
                    _Recurrence = value;
                    OnPropertyChanged( "Recurrence" );
                }
            }
        }

        public override string RecurrenceData
        {
            get
            {
                switch ( Recurrence )
                {
                    case RecurrenceValue.WeekdayOfMonth:
                        return base.RecurrenceData.Replace( REPEAT, WEEKDAYOFMONTH ).Replace( FREQUENCY, Frequency.ToString( ) ).Replace( DAY, weekday[ ( int ) Weekday ] ).Replace( WEEKDAY, weekdayOfMonth[ ( int ) WeekdayOfMonth ] ).Replace( MONTH, ( ( int ) Month ).ToString( ) );
                    case RecurrenceValue.SpecificDay:
                    default:
                        break;
                }
                return base.RecurrenceData.Replace( REPEAT, SPECIFICDAY ).Replace( FREQUENCY, Frequency.ToString( ) ).Replace( DAY, SpecificDay.ToString( ) ).Replace( MONTH, ( ( int ) Month ).ToString( ) );
            }
        }

        public int SpecificDay
        {
            get
            {
                return _SpecificDay.HasValue ? _SpecificDay.Value : 1;
            }
            set
            {
                if ( ( value != _SpecificDay ) )
                {
                    OnPropertyChanging( "SpecificDay", _SpecificDay );
                    _SpecificDay = value;
                    OnPropertyChanged( "SpecificDay" );
                }
            }
        }

        public int SpecificMonth
        {
            get
            {
                return ( int ) Month;
            }
            set
            {
                Month = ( MonthValue ) Enum.Parse( typeof( MonthValue ), value.ToString( ) );
            }
        }

        public WeekdayValue Weekday
        {
            get
            {
                return _Weekday.HasValue ? _Weekday.Value : WeekdayValue.Sunday;
            }
            set
            {
                if ( ( value != _Weekday ) )
                {
                    OnPropertyChanging( "Weekday", _Weekday );
                    _Weekday = value;
                    OnPropertyChanged( "Weekday" );
                }
            }
        }

        public WeekdayOfMonthValue WeekdayOfMonth
        {
            get
            {
                return _WeekdayOfMonth.HasValue ? _WeekdayOfMonth.Value : WeekdayOfMonthValue.First;
            }
            set
            {
                if ( ( value != _WeekdayOfMonth ) )
                {
                    OnPropertyChanging( "WeekdayOfMonth", _WeekdayOfMonth );
                    _WeekdayOfMonth = value;
                    OnPropertyChanged( "WeekdayOfMonth" );
                }
            }
        }

        #endregion Properties
    }

    public class InternalBase : Microsoft.SharePoint.Linq.ITrackOriginalValues
    {
        #region Fields

        private System.Collections.Generic.IDictionary<string, object> _originalValues;

        #endregion Fields

        #region Events

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        public event System.ComponentModel.PropertyChangingEventHandler PropertyChanging;

        #endregion Events

        #region Properties

        System.Collections.Generic.IDictionary<string, object> Microsoft.SharePoint.Linq.ITrackOriginalValues.OriginalValues
        {
            get
            {
                if ( ( null == this._originalValues ) )
                {
                    this._originalValues = new System.Collections.Generic.Dictionary<string, object>( );
                }
                return this._originalValues;
            }
        }

        #endregion Properties

        #region Methods

        protected virtual void OnPropertyChanged( string propertyName )
        {
            if ( ( null != this.PropertyChanged ) )
            {
                this.PropertyChanged( this, new System.ComponentModel.PropertyChangedEventArgs( propertyName ) );
            }
        }

        protected virtual void OnPropertyChanging( string propertyName, object value )
        {
            if ( ( null == this._originalValues ) )
            {
                this._originalValues = new System.Collections.Generic.Dictionary<string, object>( );
            }
            if ( ( false == this._originalValues.ContainsKey( propertyName ) ) )
            {
                this._originalValues.Add( propertyName, value );
            }
            if ( ( null != this.PropertyChanging ) )
            {
                this.PropertyChanging( this, new System.ComponentModel.PropertyChangingEventArgs( propertyName ) );
            }
        }

        #endregion Methods
    }
}